package org.domain.sigepac;

import java.io.IOException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.faces.component.UIComponent;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.persistence.EntityManager;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import net.sf.trugger.Transformer;
import net.sf.trugger.iteration.Iteration;

import org.apache.commons.lang3.time.DateUtils;
import org.domain.sigepac.Entity.DiasFuncionamento;
import org.domain.sigepac.Entity.Turno;
import org.jboss.seam.Component;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.faces.Redirect;

/**
 * Classe que contém métodos utilitários gerais.
 *
 * @author bruno.canto
 */
public class Utils {



  private Utils() {}

  /**
   * Retorna o hash MD5 do valor dado.
   *
   * @param value
   *          valor para cálculo do hash.
   * @return hash do valor.
   */
  public static String hash(String value) {
    try {
      MessageDigest digest = MessageDigest.getInstance("MD5");
      BigInteger hash = new BigInteger(1, digest.digest(value.getBytes()));
      return hash.toString(16);
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
      throw new Error(e);
    }
  }

  private static final char[] LETRAS =
      { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
          'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
  private static final char[] NUMEROS =
      { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };

  private static char letra() {
    return aleatorio(LETRAS);
  }

  private static char numero() {
    return aleatorio(NUMEROS);
  }

  private static char aleatorio(char[] array) {
    return array[(int) (Math.random() * array.length)];
  }

  /**
   * Gera uma senha aleatória.
   *
   * @return senha gerada.
   */
  public static String gerarSenha() {
    int letras = 5;
    int numeros = 3;
    StringBuilder senha = new StringBuilder();
    for (int i = 0 ; i < letras ; i++) {
      senha.append(letra());
    }
    for (int i = 0 ; i < numeros ; i++) {
      senha.append(numero());
    }
    return senha.toString();
  }

  public static UIComponent findComponent(FacesContext context,
      UIComponent parent, String id) {
    if (parent == null) {
      parent = context.getViewRoot();
      if (parent == null) {
        return null;
      }
    }

    if (parent.getId() != null && parent.getId().equals(id)) {
      return parent;
    } else {
      for (UIComponent comp : parent.getChildren()) {
        UIComponent found = findComponent(context, comp, id);

        if (found != null) {
          return found;
        }
      }
    }

    return null;
  }

  /**
   * @return componente com o nome informado.
   */
  public static <E> E component(String componentName) {
    return (E) Component.getInstance(componentName);
  }

  public static <E> E component(Class<?> componentClass) {
    String componentName = componentName(componentClass);
    return (E) Component.getInstance(componentName);
  }

  public static String componentName(Class<?> componentClass) {
    if(componentClass.isAnnotationPresent(Name.class)) {
      return componentClass.getAnnotation(Name.class).value();
    }
    StringBuilder componentName =
        new StringBuilder(componentClass.getSimpleName());
    char firstChar = componentName.charAt(0);
    componentName.setCharAt(0, Character.toLowerCase(firstChar));
    return componentName.toString();
  }

  public static EntityManager getEntityManager() {
    return component("entityManager");
  }

  public static void entityManagerFlush() {
    getEntityManager().flush();
  }

  public static void redirectTo(String page) {
    Redirect.instance().setViewId(page);
  }


  /**
   * Retira os acentos e caracteres especiais(n�o todos) do nome passado.
   *
   * @return nome formatado.
   */
  public static String formatarNome(String s)
  {
      String c_acento = "\340\341\342\343\344\350\351\352\353\354\355\356\357\362\363\364\365\366\371\372" +
"\373\374\375\377\347\361\300\301\302\303\304\310\311\312\313\314\315\316\317\322" +
"\323\324\325\326\331\332\333\334\335\307\321 "
;
      String s_acento = "aaaaaeeeeiiiiooooouuuuyycnAAAAAEEEEIIIIOOOOOUUUUYCN_";
      String retorno = "";
      char letra = s.charAt(0);
      for(int i = 0; i < s.length(); i++)
      {
          for(int j = 0; j < c_acento.length(); j++)
          {
              if(Character.toUpperCase(s.charAt(i)) == c_acento.charAt(j))
              {
                  letra = Character.isLowerCase(s.charAt(i)) ? Character.toLowerCase(s_acento.charAt(j)) : s_acento.charAt(j);
                  break;
              }
              letra = s.charAt(i);
          }

          retorno = retorno + letra;
      }

      return retorno;
  }

  public static <E, T> List<E> wrap(List<T> list, Transformer<E, T> transformer) {
    List<E> result = new ArrayList<E>(list.size());
    Iteration.copyTo(result).transformingWith(transformer).allElements().from(list);
    return result;
  }

  public static UIComponent findComponent(UIComponent c, String id) {
    if (id.equals(c.getId())) {
      return c;
    }
    Iterator<UIComponent> kids = c.getFacetsAndChildren();
    while (kids.hasNext()) {
      UIComponent found = findComponent(kids.next(), id);
      if (found != null) {
        return found;
      }
    }
    return null;
  }

  public static String toString(List<Turno> turnos){
	  StringBuffer str=new StringBuffer();

	  for(Turno turno:turnos){

		  str.append((str.length()>0?"/":"")).append(turno.getTurno());
	  }
	  return str.toString();
  }
  public static String toString(List<Turno> turnos,String sep){
	  StringBuffer str=new StringBuffer();

	  for(Turno turno:turnos){

		  str.append((str.length()>0?sep:"")).append(turno.getTurno());
	  }
	  return str.toString();
  }

  public static String DiasToString(List<DiasFuncionamento> dias){
	  StringBuffer str=new StringBuffer();

	  for(DiasFuncionamento diasFuncionamento:dias){
		  String sep=", ";
		  if(dias.indexOf(diasFuncionamento)==dias.size()-1)
			  sep=" e ";
		  str.append((str.length()>0?sep:"")).append(diasFuncionamento.getNome());
	  }
	  return str.toString();
  }

  public static boolean isInside(Date date,Date begin,Date end){
		if(begin!=null && end!=null){
			if( ( begin.before(date) || DateUtils.isSameDay(date, begin) ) && (end.after(date) || DateUtils.isSameDay(date, end)) )
				return true;
			return false;
		}else
			return true;
  }

	public static String formataData(Date data,String pattern){
		return new SimpleDateFormat(pattern).format(data);
	}


	public static String download(String texto, FacesContext facesContext) throws IOException{


		ExternalContext extCtx=facesContext.getExternalContext(); //component("#{facesContext.externalContext}");


		 HttpServletResponse response = (HttpServletResponse)extCtx.getResponse();

		 response.setHeader( "Content-Type", "application/vnd.ms-word;charset=windows-1252");
		 response.setHeader( "Content-Disposition", "attachment;filename=arquivo.doc");


		 try {
				ServletOutputStream os = response.getOutputStream();
				os.write(texto.getBytes());
				os.flush();
				os.close();
				facesContext.responseComplete();
			} catch(Exception e) {
			}
		return null;
	}

}
